﻿using System.ComponentModel;

namespace System.AutoUpdate.Core.Operations
{
    /// <summary>
    /// Single-Threaded background operation with a background worker
    /// </summary>
    public abstract class BackgroundOperation : BasicOperation
    {
        protected BackgroundOperation ()
        {
            Worker = new BackgroundWorker
                     {
                         WorkerSupportsCancellation = true
                     };

            Worker.DoWork += WorkerOnDoWork;
            Worker.ProgressChanged += WorkerOnProgressChanged;
            Worker.RunWorkerCompleted += WorkerOnRunWorkerCompleted;
        }

        public void Cancel ()
        {
            Worker.CancelAsync ();
        }

        protected BackgroundWorker Worker
        {
            get;
            private set;
        }

        protected void Run ()
        {
            Worker.RunWorkerAsync ();
        }

        protected abstract void WorkerOnDoWork (object sender, DoWorkEventArgs doWorkEventArgs);

        protected virtual void WorkerOnRunWorkerCompleted (object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
        {
            OperationEvent(Core.OperationEvent.Completed, this, new OperationEventArgs
            {
                UpdateInfo = Info,
                Progress = 100,
            });
        }

        protected virtual void WorkerOnProgressChanged (object sender, ProgressChangedEventArgs progressChangedEventArgs)
        {
            OperationEvent (Core.OperationEvent.Progress, this, new OperationEventArgs
                                                                {
                                                                    UpdateInfo = Info,
                                                                    Progress = progressChangedEventArgs.ProgressPercentage
                                                                });
        }
    }
}